package weaver.jobs.sinopec.utils;

import org.apache.axis.encoding.Base64;
import org.apache.commons.io.IOUtils;
import weaver.alioss.AliOSSObjectManager;
import weaver.conn.ConnStatement;
import weaver.conn.RecordSet;
import weaver.conn.RecordSetDataSource;
import weaver.docs.webservices.DocAttachment;
import weaver.docs.webservices.DocInfo;
import weaver.docs.webservices.DocServiceImpl;
import weaver.docs.webservicesformsg.AESCoder;
import weaver.formmode.setup.ModeRightInfo;
import weaver.general.BaseBean;
import weaver.general.TimeUtil;
import weaver.general.Util;
import weaver.hrm.User;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.*;
import java.util.zip.ZipInputStream;

/**
 * @author dusongsong
 * @date 2024年10月08日 10:02
 */
public class BatchDataMigrationUtil {

    public static BaseBean baseBean = new BaseBean();

    RecordSet rs = new RecordSet();

    /**
     * 批量新增明细数据
     * @param oldtablename
     * @param newtablename
     * @param formid
     * @param mainid
     * @param dataid
     * @return
     */
    public boolean addModeDetailData(String oldtablename, String newtablename, String formid, String mainid, int dataid) {
        RecordSetDataSource rsd = new RecordSetDataSource("OLDOA");
        //RecordSet rsd = new RecordSet();
        baseBean.writeLog(">>>>>addModeDetailData>>>>>oldtablename=" + oldtablename + ",oldtablename=" + newtablename + ",mainid=" + mainid + ",dataid=" + dataid);
        rsd.execute("select * from " + oldtablename + " where mainid=" + mainid);
        int counts = rsd.getCounts();
        int count = 0;
        while (rsd.next()) {
            Map<String, Object> detailDataMap = new HashMap<>();
            //遍历所有字段
            String[] dtlcolnames = rsd.getColumnName();
            for (String name : dtlcolnames) {
                name = name.toLowerCase();
                String value = Util.null2String(rsd.getString(name));
                if (!"".equals(value) || !"id".equals(name)) {
                    if (isUploadDetailField(formid, name)) {
                        value = getNewDocidById(value, 1);
                    }
                    if (isSelectDetailField(formid, name)) {
                        value = getSelectItem(formid, name, value);
                    }
                    detailDataMap.put(name, value);
                }
            }
            detailDataMap.put("mainid", dataid);
            boolean insertStatus = insertDetailData(newtablename, detailDataMap);
            if (insertStatus) {
                count++;
            }
        }
        baseBean.writeLog(">>>>>addModeDetailData>>>>>counts=" + counts + ",count=" + count);
        return counts == count;
    }

    /**
     * 批量新增日志数据
     * @param requestid
     * @param dataid
     * @param newtablename
     * @return
     */
    public boolean addModeRequestLogData(String requestid, int dataid, String newtablename) {
        RecordSetDataSource rsd = new RecordSetDataSource("OLDOA");
        //RecordSet rsd = new RecordSet();
        baseBean.writeLog(">>>>>addModeRequestLogData>>>>>requestid=" + requestid + ",newtablename=" + newtablename + ",dataid=" + dataid);
        rsd.execute("select * from workflow_requestlog where requestid=" + requestid);
        int counts = rsd.getCounts();
        int count = 0;
        while (rsd.next()) {
            Map<String, Object> detailDataMap = new HashMap<>();
            detailDataMap.put("lcid", Util.null2String(rsd.getString("requestid")));
            detailDataMap.put("workflowid", Util.null2String(rsd.getString("workflowid")));
            String nodeid = Util.null2String(rsd.getString("nodeid"));
            detailDataMap.put("nodeid", getNodenameByid(nodeid));
            String logtype = Util.null2String(rsd.getString("logtype"));
            detailDataMap.put("logtype", getLogtypeName(logtype));
            detailDataMap.put("operatedate", Util.null2String(rsd.getString("operatedate")));
            detailDataMap.put("operatetime", Util.null2String(rsd.getString("operatetime")));
            detailDataMap.put("operator", Util.null2String(rsd.getString("operator")));
            detailDataMap.put("remark1", Util.null2String(rsd.getString("remark1")));
            detailDataMap.put("remark", Util.null2String(rsd.getString("remark")));
            detailDataMap.put("receivedpersons", Util.null2String(rsd.getString("receivedpersons")));
            detailDataMap.put("operatordept", Util.null2String(rsd.getString("operatordept")));
            detailDataMap.put("receivedpersonids", Util.null2String(rsd.getString("receivedpersonids")));
            detailDataMap.put("mainid", dataid);
            detailDataMap.put("requestname", getRequestInfo(requestid).get("requestname"));
            boolean insertStatus = insertDetailData(newtablename, detailDataMap);
            if (insertStatus) {
                count++;
            }
        }
        baseBean.writeLog(">>>>>addModeRequestLogData>>>>>counts=" + counts + ",count=" + count);
        return counts == count;
    }

    /**
     * 获取明细表名
     * @param billid
     * @return
     */
    public List<String> getDetailtable(String billid) {
        List<String> detailtableList = new ArrayList<>();
        //RecordSet rs = new RecordSet();
        rs.executeQuery("select detailtable from workflow_billfield  where billid=? and detailtable is not null group by detailtable", billid);
        while (rs.next()) {
            String detailtable = Util.null2String(rs.getString("detailtable"));
            detailtableList.add(detailtable);
        }
        return detailtableList;
    }

    /**
     *@Description: 建模权限重构
     */
    private void newModeRight(int userid, int formmodeid, int id) {
        ModeRightInfo modeRightInfo = new ModeRightInfo();
        modeRightInfo.setNewRight(true);
        modeRightInfo.editModeDataShare(userid, formmodeid, id);
    }

    /**
     * 将数据插入表单建模
     *
     * @param tablename
     * @param map
     * @return
     */
    public int insertModelData(String tablename, Map<String, Object> map) {
        int dataid = 0;
        RecordSet rs = new RecordSet();
        try {
            //查询该模块表名
            String uuid = UUID.randomUUID().toString();
            int formmodeid = getFormmodeid(tablename);
            String insSql = "insert into " + tablename
                    + "(modeuuid,modedatacreater,modedatacreatedate,modedatacreatetime,formmodeid)values(?,?,?,?,?)";
            Object[] params = {uuid, 1, TimeUtil.getCurrentDateString(), TimeUtil.getOnlyCurrentTimeString(), formmodeid};
            if (rs.executeUpdate(insSql, params)) {
                dataid = ModeUUID2DataId(tablename, uuid);
                if (dataid > 0) {
                    //遍历数据 进行update
                    String updatesql = "update " + tablename + " set ";
                    Set<String> keySet = map.keySet();
                    for (String key : keySet) {
                        updatesql += key + "='" + map.get(key).toString() + "',";
                    }
                    if (updatesql.endsWith(",")) {
                        updatesql = updatesql.substring(0, updatesql.length() - 1);
                        updatesql += " where id=" + dataid;
                        boolean updateStat = rs.executeUpdate(updatesql);
                        baseBean.writeLog(">>>>>insertModelData>>>>updatesql=" + updatesql);
                        if (!updateStat) {
                            dataid = 0;
                        }
                    }
                    //进行权限重构
                    newModeRight(1, formmodeid, dataid);
                }
            }
        } catch (Exception e) {
            baseBean.writeLog(">>>>>insertModelData>>>>" + e.getMessage());
        }

        return dataid;
    }

    /**
     * 更新明细数据
     *
     * @param tablename
     * @param map
     * @return
     */
    public boolean insertDetailData(String tablename, Map<String, Object> map) {
        String insertsql = "insert into " + tablename + "";
        String keyString = "";
        String valueString = "";
        boolean flag = false;
        RecordSet rs = new RecordSet();
        Set<String> keySet = map.keySet();
        try {
            for (String key : keySet) {
                if (map.get(key) == null || "".equals(map.get(key).toString())) {
                    continue;
                }
                keyString += key + ",";
                valueString += "'" + map.get(key).toString() + "',";
            }
            if (keyString.endsWith(",")) {
                keyString = keyString.substring(0, keyString.length() - 1);
            }
            if (valueString.endsWith(",")) {
                valueString = valueString.substring(0, valueString.length() - 1);
            }
            insertsql += "(" + keyString + ") values(" + valueString + ")";
            baseBean.writeLog(">>>>>insertDetailData>>>>insertsql=" + insertsql);
            flag = rs.executeUpdate(insertsql);
        } catch (Exception e) {
            baseBean.writeLog(">>>>>insertDetailData>>>>" + e.getMessage());
        }
        return flag;
    }

    /**
     *@Description: 根据建模表名和UUID获取数据ID 常用于建模的权限重构获取数据ID
     */
    private int ModeUUID2DataId(String tablename, String uuid) {
        RecordSet rs = new RecordSet();
        rs.executeQuery("select id from " + tablename + " where modeuuid =?", uuid);
        rs.next();
        return Util.getIntValue(rs.getString(1));
    }

    /**
     *@Description: 获取建模Id
     */
    private int getFormmodeid(String tablename) {
        RecordSet rs = new RecordSet();
        String sql = "select m.id from modeinfo m left join WORKFLOW_BILL b on m.formid = b.id where b.tablename = ?";
        rs.executeQuery(sql, tablename);
        rs.next();
        return Util.getIntValue(rs.getString("id"));
    }

    /**
     *@Description: 返回文件流   已经经过脱密、解压
     */
    public String getNewDocidById(String docid, int userid) {
        String docids = "";
        try {
            baseBean.writeLog(">>>>>getNewDocidById>>>>>docid="+docid);
            RecordSetDataSource rsd = new RecordSetDataSource("OLDOA");
            //RecordSet rsd = new RecordSet();
            String sql = "select imagefileid,fileRealPath,imagefilename,isZip,isaesencrypt,aescode,tokenKey,storageStatus  from ImageFile " +
                    " where imagefileid in (select imagefileid from docimagefile where docid in (" + docid + "))";
            rsd.execute(sql);
            while (rsd.next()) {
                InputStream imagefile = null;
                String imagefileid = Util.null2String(rsd.getString("imagefileid"));
                String static_fileRealPath = Util.null2String(rsd.getString("fileRealPath"));
                String imagefilename = Util.null2String(rsd.getString("imagefilename"));
                String static_isZip = Util.null2String(rsd.getString("isZip"));
                int static_isaesencrypt = Util.getIntValue(rsd.getString("isaesencrypt"), 0);
                String static_aescode = Util.null2String(rsd.getString("aescode"));
                String static_tokenKey = Util.null2String(rsd.getString("tokenKey"));
                String static_storageStatus = Util.null2String(rsd.getString("storageStatus"));
                String linuxPath = windowsToLinux(static_fileRealPath);
                static_fileRealPath = "/opt/weaver/ecology/oldfilesystem" + linuxPath.substring(linuxPath.indexOf("filesystem") + 10);
                baseBean.writeLog(">>>>>getNewDocidById>>>>>static_fileRealPath="+static_fileRealPath);
                boolean isonlyAliOSS = false;
                if (!static_tokenKey.equals("") && static_storageStatus.equals("1") && AliOSSObjectManager.isonlyAliOSS()) {
                    isonlyAliOSS = true;
                }

                if (isonlyAliOSS) {
                    imagefile = weaver.alioss.AliOSSObjectUtil.downloadFile(static_tokenKey);
                } else {
                    if (static_fileRealPath != null && !static_fileRealPath.equals("")) {
                        File thefile = new File(static_fileRealPath);
                        if (static_isZip.equals("1")) {
                            ZipInputStream zin = new ZipInputStream(new FileInputStream(thefile));
                            if (zin.getNextEntry() != null) {
                                imagefile = new BufferedInputStream(zin);
                            }
                        } else {
                            imagefile = new BufferedInputStream(new FileInputStream(thefile));
                        }
                    } else {
                        ConnStatement statement = null;
                        try {
                            statement = new ConnStatement();
                            boolean isoracle = ("oracle").equals(statement.getDBType());
                            statement.setStatementSql("select imagefile from ImageFile where imagefileid = " + imagefileid);
                            statement.executeQuery();
                            if (statement.next()) {
                                if (isoracle) {
                                    imagefile = new BufferedInputStream(statement.getBlobBinary("imagefile"));
                                } else {
                                    imagefile = new BufferedInputStream(statement.getBinaryStream("imagefile"));
                                }
                            }
                        } catch (Exception ex) {
                        } finally {
                            try {
                                if (statement != null) {
                                    statement.close();
                                }
                            } catch (Exception ex) {
                                ex.printStackTrace();
                            }
                        }
                    }
                    if (static_isaesencrypt == 1) {
                        imagefile = AESCoder.decrypt(imagefile, static_aescode);
                    }

                }
                int newdocid = createImagefile(userid, imagefile, imagefilename, 157);
                docids += newdocid + ",";
            }
            baseBean.writeLog(">>>>>getNewDocidById>>>>>docids="+docids);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return docids;
    }

    /**
     *@Description: 创建文档单附件
     */
    private int createImagefile(int userid, InputStream input, String rawFileName, int seccategory) {
        BaseBean log = new BaseBean();
        byte[] content = null;
        // 上传附件，创建html文档
        int docid = -1;
        DocServiceImpl docserviceimpl = new DocServiceImpl();
        DocAttachment[] docattachment = new DocAttachment[1];
        String docsubject = ""; //文档标题
        String keyword = ""; //文档内容
        String filetype = "";
        String filename = "";
        if (rawFileName.lastIndexOf(".") > -1) {
            filetype = rawFileName.substring(rawFileName.lastIndexOf(".") + 1);
            filename = rawFileName.substring(0, rawFileName.lastIndexOf("."));
        }
        try {
            content = IOUtils.toByteArray(input);
            DocAttachment da = new DocAttachment();
            da.setFilename(filename + "." + filetype);//附件标题
            da.setFilecontent(Base64.encode(content)); //附件内容
            da.setFiletype(filetype); //imagefiletype
            da.setImagefilename(filename + "." + filetype);// 附件标题
            da.setIszip(1);//是否压缩
            da.setIsAesEncrype(0);//是否加密
            da.setAesCode("0");
            da.setIsextfile("1"); //附件是否是office类型
            if (filetype.equalsIgnoreCase("doc")) {
                da.setDocfiletype("3");
            } else if (filetype.equalsIgnoreCase("xls")) {
                da.setDocfiletype("4");
            } else if (filetype.equalsIgnoreCase("ppt")) {
                da.setDocfiletype("5");
            } else if (filetype.equalsIgnoreCase("wps")) {
                da.setDocfiletype("6");
            } else if (filetype.equalsIgnoreCase("docx")) {
                da.setDocfiletype("7");
            } else if (filetype.equalsIgnoreCase("xlsx")) {
                da.setDocfiletype("8");
            } else if (filetype.equalsIgnoreCase("pptx")) {
                da.setDocfiletype("9");
            } else {
                da.setDocfiletype("2");
            }
            docattachment[0] = da;
            docsubject = filename;
            keyword = filename;
            DocInfo doc = new DocInfo();//创建文档
            doc.setSeccategory(seccategory);//子目录id
            doc.setDocSubject(docsubject);//标题
            doc.setDoccontent("");//文档内容
            doc.setKeyword(keyword);
            doc.setAttachments(docattachment);
            if (!"".equals(userid)) {
                User user = new User(userid);
                docid = docserviceimpl.createDocByUser(doc, user);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.writeLog("e:" + e);
        }
        return docid;
    }

    /**
     * windows路径转linux路径
     * @param windowsPath
     * @return
     */
    private String windowsToLinux(String windowsPath) {
        if (windowsPath == null || windowsPath.isEmpty()) {
            return windowsPath;
        }

        // 去除末尾的反斜杠（如果存在）
        if (windowsPath.endsWith("\\")) {
            windowsPath = windowsPath.substring(0, windowsPath.length() - 1);
        }

        // 替换盘符和路径分隔符
        return windowsPath.replace("\\", "/");
    }

    /**
     * 判断主表字段是否是上传附件字段
     * @param billid
     * @param fieldname
     * @return
     */
    public boolean isUploadMainField(String billid, String fieldname) {
        //RecordSet rs = new RecordSet();
        String sql = "select id from workflow_billfield  where billid=? and fieldname=? \n" +
                " and fieldhtmltype='6' and type='1' and detailtable is null ";
        rs.executeQuery(sql, billid, fieldname);
        rs.next();
        return !"".equals(Util.null2String(rs.getString("id")));
    }

    /**
     * 判断主表字段是否是下拉框
     * @param billid
     * @param fieldname
     * @return
     */
    public boolean isSelectMainField(String billid, String fieldname) {
        //RecordSet rs = new RecordSet();
        String sql = "select id from workflow_billfield  where billid=? and fieldname=? \n" +
                " and fieldhtmltype='5' and type='1' and detailtable is null ";
        rs.executeQuery(sql, billid, fieldname);
        rs.next();
        return !"".equals(Util.null2String(rs.getString("id")));
    }

    /**
     * 判断明细表字段是否是上传附件字段
     * @param billid
     * @param fieldname
     * @return
     */
    private boolean isUploadDetailField(String billid, String fieldname) {
        RecordSet rs = new RecordSet();
        String sql = "select id from workflow_billfield  where billid=? and fieldname=? \n" +
                "and fieldhtmltype='6' and type='1' and detailtable is not null ";
        rs.executeQuery(sql, billid, fieldname);
        rs.next();
        return !"".equals(Util.null2String(rs.getString("id")));
    }

    /**
     * 判断明细表字段是否是下拉框
     * @param billid
     * @param fieldname
     * @return
     */
    private boolean isSelectDetailField(String billid, String fieldname) {
        RecordSet rs = new RecordSet();
        String sql = "select id from workflow_billfield  where billid=? and fieldname=? \n" +
                "and fieldhtmltype='5' and type='1' and detailtable is not null ";
        rs.executeQuery(sql, billid, fieldname);
        rs.next();
        return !"".equals(Util.null2String(rs.getString("id")));
    }

    //根据表单和字段获取下拉框值
    public String getSelectItem(String billid, String fieldname, String selectvalue) {
        RecordSet rs = new RecordSet();
        String sql = "select t1.selectvalue,t1.selectname from workflow_selectitem t1 left join workflow_billfield t2\n" +
                "on t1.fieldid=t2.id where t2.billid=? and t2.fieldname=? and t1.selectvalue=?";
        rs.executeQuery(sql, billid, fieldname, selectvalue);
        rs.next();
        return Util.null2String(rs.getString("selectname"));
    }

    /**
     * 获取日志类型名称
     * @param value
     * @return
     */
    private static String getLogtypeName(String value) {
        String name = "";
        switch (value) {
            case "0":
                name = "批准";
                break;
            case "1":
                name = "保存";
                break;
            case "2":
                name = "提交";
                break;
            case "3":
                name = "退回";
                break;
            case "4":
                name = "重新打开";
                break;
            case "5":
                name = "删除";
                break;
            case "6":
                name = "激活";
                break;
            case "7":
                name = "转发";
                break;
            case "9":
                name = "批注";
                break;
            case "a":
                name = "意见征询";
                break;
            case "b":
                name = "意见征询回复";
                break;
            case "e":
                name = "强制归档";
                break;
            case "h":
                name = "转办";
                break;
            case "i":
                name = "干预";
                break;
            case "j":
                name = "转办反馈";
                break;
            case "s":
                name = "督办";
                break;
            case "t":
                name = "抄送";
                break;
            default:
        }
        return name;
    }

    /**
     * @Description: 获取流程请求标题
     */
    public Map<String, String> getRequestInfo(String requestid) {
        Map<String, String> resultMap = new HashMap<>();
        RecordSetDataSource rsd = new RecordSetDataSource("OLDOA");
        rsd.execute("select workflowid,requestname from workflow_requestbase where requestid='" + requestid + "'");
        rsd.next();
        resultMap.put("workflowid", Util.null2String(rsd.getString("workflowid")));
        resultMap.put("requestname", Util.null2String(rsd.getString("requestname")));
        return resultMap;
    }
    /**
     * @Description: 获取节点名称
     */
    public String getNodenameByid(String nodeid) {
        RecordSetDataSource rsd = new RecordSetDataSource("OLDOA");
        rsd.execute("select nodename from workflow_nodebase where id='" + nodeid + "'");
        rsd.next();
        return Util.null2String(rsd.getString("nodename"));
    }
}
